package com.juyu.miliao.api.dao.redis;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.api.dao.mysql.CommentReplyInfoDao;
import com.juyu.miliao.api.dao.mysql.DynamicCommentInfoDao;
import com.juyu.miliao.api.dao.redis.usercache.UserCacheVo;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.CommentReplyInfo;
import com.juyu.miliao.api.domain.DynamicCommentInfo;
import com.juyu.miliao.api.domain.dto.DynamicCommentInfoDTO;
import com.juyu.miliao.common.constant.DynamicCommentInfoRedisKey;
import com.juyu.miliao.common.constant.RedisKeyPrefix;
import com.juyu.miliao.common.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author xuanqicheng
 * @create 2019-21-13:05
 */
@Repository
public class DynamicCommentInfoRedisDao {

    private final Logger log = LoggerFactory.getLogger("dynamicRabbitMQ");

    private static final String SEND_DYNAMIC_COMMENT_NUMBER_BY_TIME_AND_USERID = RedisKeyPrefix.MI_LIAO_API_KEY
            + "SEND_DYNAMIC_COMMENT_NUMBER_BY_TIME_AND_USERID:";

    private static final String SEND_DYNAMIC_COMMENT_REPLY_NUMBER_BY_TIME_AND_USERID = RedisKeyPrefix.MI_LIAO_API_KEY
            + "SEND_DYNAMIC_COMMENT_REPLY_NUMBER_BY_TIME_AND_USERID:";

    @Autowired
    private DynamicCommentInfoDao dynamicCommentInfoDao;

    @Autowired
    private CommentReplyInfoDao commentReplyInfoDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserInfoCache userInfoCache;

    public DynamicCommentInfo  addDynamicComment(DynamicCommentInfoDTO dynamicCommentInfoDTO) {

        DynamicCommentInfo dynamicCommentInfo = new DynamicCommentInfo();

        BeanUtils.copyProperties(dynamicCommentInfoDTO, dynamicCommentInfo);

        dynamicCommentInfoDao.addDynamicComment(dynamicCommentInfo);

        deleteDynamicCommentInfoByDynamicId(dynamicCommentInfo.getDynamicId());
        return dynamicCommentInfo;
    }

    /**
     * 删除动态评论缓存
     * @param dynamicId
     */
    private void deleteDynamicCommentInfoByDynamicId(long dynamicId) {
        String pageHashKey = DynamicCommentInfoRedisKey.DynamicCommentPageByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        String pageCountKey = DynamicCommentInfoRedisKey.DynamicCommentCountByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        Set<String> deleteSet = new HashSet<>();
        deleteSet.add(pageHashKey);
        deleteSet.add(pageCountKey);
        stringRedisTemplate.delete(deleteSet);
    }

    /**
     * 添加评论回复信息
     * @param commentReplyInfo
     */
    public void addCommentReply(CommentReplyInfo commentReplyInfo) {

        commentReplyInfoDao.addCommentReply(commentReplyInfo);

        String key = DynamicCommentInfoRedisKey.CommentReplyInfoByCommentId.REDIS_KEY
                .getKeyFormat(commentReplyInfo.getCommentId());

        stringRedisTemplate.delete(key);
    }


    /**
     * 根据评论id,获取回复新
     * @param commentId
     * @return
     */
    public List<CommentReplyInfo> getCommentReplyInfoByCommentId(Long commentId) {

        String key = DynamicCommentInfoRedisKey.CommentReplyInfoByCommentId.REDIS_KEY.getKeyFormat(commentId);

        String temp = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.isEmpty(temp)) {
            return JSONArray.parseArray(temp, CommentReplyInfo.class);
        } else {
            List<CommentReplyInfo> list = commentReplyInfoDao.getCommentReplyInfoByCommentId(commentId);
            if (list.size() > 0) {
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(list), 30, TimeUnit.MINUTES);
            }
            return list;
        }
    }


    /**
     * 根据评论id,获取评论信息
     * @param id
     * @return
     */
    public DynamicCommentInfo getDynamciCommentInfoByCommentId(long id) {
        String key = DynamicCommentInfoRedisKey.DynamicCommentByCommentId.REDIS_KEY.getKeyFormat(id);

        String temp = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.isEmpty(temp)) {
            return JSONObject.parseObject(temp, DynamicCommentInfo.class);
        } else {
            DynamicCommentInfo obj = dynamicCommentInfoDao.getDynamciCommentById(id);
            if (obj != null) {
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(obj), 30, TimeUnit.MINUTES);
            }
            return obj;
        }

    }

    /**
     * 根据动态id,获取评论分页数据
     * @param dynamicId
     * @param startNum
     * @param pageSize
     * @return
     */
    public List<DynamicCommentInfo> getDynamicCommentPageByDynamicId(long dynamicId, int startNum, int pageSize) {

        String key = DynamicCommentInfoRedisKey.DynamicCommentPageByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);

        String hashKey = DynamicCommentInfoRedisKey.DynamicCommentPageByDynamicId.HASH_KEY.getHashKeyFormat(startNum, pageSize);



        String temp = (String) stringRedisTemplate.opsForHash().get(key, hashKey);

        List<DynamicCommentInfo> list;

        if (!StringUtils.isEmpty(temp)) {
            list = JSONArray.parseArray(temp, DynamicCommentInfo.class);
        } else {
            list = dynamicCommentInfoDao.getDynamicCommentPageByDynamicId(dynamicId, startNum, pageSize);
            if (list.size() > 0) {
                stringRedisTemplate.opsForHash().put(key, hashKey, JSONObject.toJSONString(list));
                stringRedisTemplate.expire(key, 30, TimeUnit.MINUTES);
            }
        }

        return list;
    }

    /**
     * 根据动态id,获取对应评论数量
     * @param dynamicId
     * @return
     */
    public int getDynamicCommentPageCountByDynamicId(long dynamicId) {
        String countKey = DynamicCommentInfoRedisKey.DynamicCommentCountByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        String countTemp =stringRedisTemplate.opsForValue().get(countKey);
        int size = 0;
        if (!StringUtils.isEmpty(countTemp)) {
                size = Integer.parseInt(countTemp);
        } else {
            size= dynamicCommentInfoDao.getDynamicCommentCountByDynamicId(dynamicId);
            stringRedisTemplate.opsForValue().set(countKey, Integer.toString(size), 30, TimeUnit.MINUTES);
        }

        return size;
    }

    /**
     * 根据评论信息,删除所有相关的缓存
     * @param obj 评论id
     */
    public void deleteDynamicCommentInfo(DynamicCommentInfo obj){

        Set<String> deleteSet = new HashSet<>();

        String pageHashKey = DynamicCommentInfoRedisKey.DynamicCommentPageByDynamicId
                .REDIS_KEY.getKeyFormat(obj.getDynamicId());

        deleteSet.add(pageHashKey);

        String pageCountKey = DynamicCommentInfoRedisKey.DynamicCommentCountByDynamicId
                .REDIS_KEY.getKeyFormat(obj.getDynamicId());

        deleteSet.add(pageCountKey);

        String dynamicCommentByCommentIdKey = DynamicCommentInfoRedisKey.DynamicCommentByCommentId
                .REDIS_KEY.getKeyFormat(obj.getId());

        deleteSet.add(dynamicCommentByCommentIdKey);

        String replyKey = DynamicCommentInfoRedisKey.CommentReplyInfoByCommentId.REDIS_KEY
                .getKeyFormat(obj.getId());


        deleteSet.add(replyKey);

        log.info("产出评论缓存key:"+JSONObject.toJSONString(deleteSet));
        stringRedisTemplate.delete(deleteSet);

    }


    /**
     * 删除评论回复信息缓存
     * @param commentReplyInfo
     */
    public void deleteCommentReplyInfo(CommentReplyInfo commentReplyInfo) {

        Set<String> set = new HashSet<>();

        String key = DynamicCommentInfoRedisKey.CommentReplyInfoByCommentId.REDIS_KEY
                .getKeyFormat(commentReplyInfo.getCommentId());

        set.add(key);

        stringRedisTemplate.delete(set);
    }

    /**
     * 获取当前用户发送评论的次数
     * @return
     */
    public int getSendCommentNumber(long userId) {
        int sendNumber = 0;
        String key = SEND_DYNAMIC_COMMENT_NUMBER_BY_TIME_AND_USERID+ LocalDate.now().toString()+":"+userId;
        String target =stringRedisTemplate.opsForValue().get(key);
        if(!StringUtils.isEmpty(target)){
            sendNumber = Integer.parseInt(target);
        }
        return sendNumber;
    }

    /**
     * 更新当前用户评论的次数
     * @param userId
     */
    public void incrementDynamicCommentNumber(long userId) {
        String key = SEND_DYNAMIC_COMMENT_NUMBER_BY_TIME_AND_USERID+ LocalDate.now().toString()+":"+userId;
        UserCacheVo userInfo = userInfoCache.getUserCacheInfo(userId);
        if(userInfo.getIsVip()!=1 && userInfo.getIsSvip()!=1
                && userInfo.getIsPlatinumVip()!=1 && userInfo.getIsHost()!=1){
            stringRedisTemplate.opsForValue().increment(key,1);

            LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0)
                    .withMinute(0).withSecond(0).withNano(0);

            long expireTime = DateUtil.getTheRemainingTimesOfTheDay(midnight, TimeUnit.MINUTES);

            stringRedisTemplate.expire(key,expireTime,TimeUnit.MINUTES);
        }
    }

    /**
     * 获取当前用户回复评论的次数
     * @param userId
     * @return
     */
    public int getSendCommentReplyNumber(long userId) {

        String key = SEND_DYNAMIC_COMMENT_REPLY_NUMBER_BY_TIME_AND_USERID+ LocalDate.now().toString()+":"+userId;
        String target =stringRedisTemplate.opsForValue().get(key);

        if(!StringUtils.isEmpty(target)){
            return Integer.parseInt(target);
        }else{
           return 0;
        }

    }

    /**
     * 更新当前用户回复评论的次数
     * @param userId
     */
    public void incrementDynamicCommentReplyNumber(long userId) {

        String key = SEND_DYNAMIC_COMMENT_REPLY_NUMBER_BY_TIME_AND_USERID+ LocalDate.now().toString()+":"+userId;
        UserCacheVo userInfo = userInfoCache.getUserCacheInfo(userId);
        if(userInfo.getIsHost()!=1&&userInfo.getIsVip()!=1 && userInfo.getIsSvip()!=1
                && userInfo.getIsPlatinumVip()!=1){
            stringRedisTemplate.opsForValue().increment(key,1);

            LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0)
                    .withMinute(0).withSecond(0).withNano(0);

            long expireTime = DateUtil.getTheRemainingTimesOfTheDay(midnight, TimeUnit.HOURS);

            stringRedisTemplate.expire(key,expireTime,TimeUnit.HOURS);
        }
    }
}
